package com.ant.business.system.service.impl;

import com.ant.business.system.entity.Module;
import com.ant.business.system.entity.User;
import com.ant.business.system.mapper.UserDao;
import com.ant.business.system.service.ModuleService;
import com.ant.business.system.service.UserService;
import com.ant.business.system.vo.UserVo;
import com.ant.common.constant.SystemConstant;
import com.ant.common.exceptions.BusinessException;
import com.ant.common.utils.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户管理Service实现类
 *
 * @author
 * @description
 * @create 2021-03-22 14:25:56
 */
@Service("userService")
@Transactional(rollbackFor = Throwable.class)
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    private final UserDao userDao;
    private final ModuleService moduleService;

    public UserServiceImpl(UserDao userDao, ModuleService moduleService) {
        this.moduleService = moduleService;
        this.userDao = userDao;
    }

    /**
     * 分页查询列表
     *
     * @param page
     * @param limit
     * @return
     */
    @Override
    public PageInfo<User> getList(int page, int limit, FastMap param) {
        UserVo user = UserThreadLocal.getUser();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("delete_flag", SystemConstant.DELETE_STATUS.UN_DELETE.getCode()).eq("unit_id", user.getUnitId());

        if (StringUtil.isNotEmpty(param.getString("userName"))) {
            wrapper.like("user_name", param.getString("userName"));
        }

        if (StringUtil.isNotEmpty(param.getString("mobile"))) {
            wrapper.like("mobile", param.getString("mobile"));
        }

        String status = param.getString("status");
        if (StringUtil.isNotEmpty(status)) {
            if (param.getInt("status") != -1) {
                wrapper.eq("status", param.getInt("status"));
            }
        }

        PageHelper.startPage(page, limit);
        List<User> list = userDao.selectList(wrapper);
        return new PageInfo<User>(list);
    }

    /**
     * 检查用户信息
     *
     * @param user
     * @return
     */
    private boolean checkInfoExists(User user) {
        UserVo userVo = UserThreadLocal.getUser();
        List<User> userList = this.list(new QueryWrapper<User>()
                .and(orWrapper -> orWrapper.eq("user_name", user.getUserName()).or()
                        .eq("user_code", user.getUserCode())).eq("unit_id", userVo.getUnitId()));
        return userList.size() != 0;
    }

    /**
     * 新增信息
     *
     * @param user
     */
    @Override
    @SneakyThrows
    public void saveOne(User user) {
        UserVo userVo = UserThreadLocal.getUser();
        if (checkInfoExists(user)) {
            throw new BusinessException("用户名称不能重复");
        }
        user.setPassword(Md5Util.md5(SystemConstant.INIT_PASSWORD, user.getMobile()));
        user.setStatus(SystemConstant.USER_STATUS.ACCEPTED.getCode());
        user.setDeleteFlag(SystemConstant.DELETE_STATUS.UN_DELETE.getCode());

        if (Objects.isNull(user.getUserType())) {
            user.setUserType(SystemConstant.USER_TYPE.UNIT_USER.getCode());
        }

        user.setUnitId(userVo.getUnitId());
        LocalBeanUtil.setLoginUserInfo(user);
        int count = userDao.insert(user);
        if (count != 1) {
            throw new BusinessException("保存用户失败");
        }
    }

    /**
     * 更新信息
     *
     * @param user
     */
    @Override
    @SneakyThrows
    public void update(User user) {
        LocalBeanUtil.updateLoginUserInfo(user);
        int count = userDao.updateById(user);
        if (count != 1) {
            throw new BusinessException("更新用户失败");
        }
    }

    /**
     * 删除信息
     *
     * @param primaryKey
     */
    @Override
    @SneakyThrows
    public void delete(String primaryKey) {
        User user = userDao.selectById(primaryKey);

        User newUser = new User();
        newUser.setUserId(Integer.valueOf(primaryKey));
        LocalBeanUtil.updateLoginUserInfo(newUser);
        newUser.setDeleteFlag(SystemConstant.DELETE_STATUS.DELETED.getCode());
        newUser.setUserName(user.getUserName() + "_" + IdWorker.get32UUID());

        int count = userDao.updateById(newUser);
        if (count != 1) {
            throw new BusinessException("删除用户失败");
        }
    }

    /**
     * 通过电话获取用户
     *
     * @param mobile
     * @param password
     * @return
     */
    @Override
    @SneakyThrows
    public List<User> getUserByMobile(String mobile, String password) {
        String md5 = Md5Util.md5(password, mobile);
        return this.list(new QueryWrapper<User>().eq("mobile", mobile).eq("password", md5).eq("delete_flag", SystemConstant.DELETE_STATUS.UN_DELETE.getCode()));
    }

    /**
     * 修改密码
     *
     * @param oldPassword
     * @param newPassword
     */
    @Override
    @SneakyThrows
    public void changePassword(String oldPassword, String newPassword) {
        UserVo userVo = UserThreadLocal.getUser();

        User oldUser = this.getById(userVo.getUserId());
        String oldPassMd5 = Md5Util.md5(oldPassword, oldUser.getMobile());
        if (!oldPassMd5.equals(oldUser.getPassword())) {
            throw new BusinessException("原密码输入不正确");
        }

        String newPassMd5 = Md5Util.md5(newPassword, oldUser.getMobile());
        User user = new User();
        user.setUserId(oldUser.getUserId());
        user.setPassword(newPassMd5);
        this.update(user);
    }

    /**
     * 查询所有用户不分页
     *
     * @param param
     * @return
     */
    @Override
    public List<User> getAllList(FastMap param) {
        UserVo user = UserThreadLocal.getUser();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("delete_flag", SystemConstant.DELETE_STATUS.UN_DELETE.getCode()).eq("unit_id", user.getUnitId());

        if (StringUtil.isNotEmpty(param.getString("userName"))) {
            wrapper.like("user_name", param.getString("userName"));
        }

        if (StringUtil.isNotEmpty(param.getString("mobile"))) {
            wrapper.like("mobile", param.getString("mobile"));
        }

        return this.list(wrapper);
    }

    /**
     * 通过角色查询用户列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<User> getUserByRoleId(Integer roleId) {
        UserVo user = UserThreadLocal.getUser();
        return userDao.getUserByRoleId(roleId, user.getUnitId());
    }

    /**
     * 跳过密码验证
     *
     * @param mobile
     * @return
     */
    @Override
    @SneakyThrows
    public List<User> getUserNoPass(String mobile) {
        return this.list(new QueryWrapper<User>().eq("mobile", mobile).eq("delete_flag", SystemConstant.DELETE_STATUS.UN_DELETE.getCode()));
    }

    /**
     * 获取模块信息
     *
     * @return
     */
    @Override
    public List<FastMap> getModuleInfo() {
        UserVo user = UserThreadLocal.getUser();
        List<Module> moduleList = moduleService.getModuleListByUser(user);
        for (Module module : moduleList) {
            Module.Meta meta = new Module.Meta();
            meta.setTitle(module.getTitle());
            meta.setIcon(module.getIcon());
            meta.setAffix(false);
            module.setMeta(meta);
        }

        List<FastMap> newList = new ArrayList<>();
        // index == 1 为首页
        int index = 2;
        Map<String, List<Module>> groupMap = moduleList.stream().collect(Collectors.groupingBy(Module::getModuleGroupPath));
        for (Map.Entry<String, List<Module>> entry : groupMap.entrySet()) {
            String groupId = entry.getKey();
            List<Module> value = entry.getValue();
            String icon = "form";
            if (value.size() > 0) {
                Module module = value.get(0);
                icon = module.getIcon();
            }
            FastMap module = new FastMap();
            module.put("path", groupId);

            FastMap meta = new FastMap();
            meta.put("title", groupId);
            meta.put("icon", icon);
            meta.put("affix", false);
            module.put("meta", meta);
            module.put("orderBy", index);

            List<FastMap> children = new ArrayList<>();
            for (Module child : value) {
                FastMap childMap = new FastMap();
                childMap.put("path", child.getPath());
                FastMap metaChild = new FastMap();
                metaChild.put("title", child.getTitle());
                metaChild.put("icon", child.getIcon());
                metaChild.put("affix", false);
                childMap.put("meta", metaChild);
                childMap.put("orderBy", child.getOrderBy());
                children.add(childMap);
            }
            module.put("children", children);
            newList.add(module);
            index++;
        }

        FastMap dashboard = new FastMap();
        dashboard.put("path", "dashboard");
        dashboard.put("orderBy", 1);
        FastMap meta = new FastMap();
        meta.put("title", "dashboard");
        meta.put("icon", "dashboard");
        meta.put("affix", true);
        dashboard.put("meta", meta);
        newList.add(dashboard);

        return newList.stream().sorted(Comparator.comparing(x -> x.getInt("orderBy"))).collect(Collectors.toList());
    }
}
